import re
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import os
import datetime
from matplotlib import rcParams

# 设置 Matplotlib 支持中文
rcParams['font.sans-serif'] = ['SimHei']  # 设置字体为黑体
rcParams['axes.unicode_minus'] = False   # 解决负号显示问题


# 创建输出文件夹
output_dir = "output"
if not os.path.exists(output_dir):
    os.makedirs(output_dir)

# 读取天气数据
with open('weather.txt', 'r', encoding='utf-8') as file:
    data = file.readlines()

# 存储所有数据的列表
weather_data = []
city_name = None

# 正则表达式：匹配日期、天气、温度、风速等信息
pattern = re.compile(r'(\d{1,2})日.*?:(\w+),(\d+)/(-?\d+)℃,([^,]+),([^\n]+)')

# 解析每一行数据
for line in data:
    line = line.strip()  # a去除多余的空格和换行符
    if not line:  # 空行表示城市名的结束
        continue
    if line[0].isalpha():  # 判断这一行是城市名
        city_name = line.strip()  # 获取城市名称
    else:
        # 解析天气信息
        match = pattern.match(line)
        if match:
            date = match.group(1)
            cloud = match.group(2)
            high_temp = int(match.group(3))
            low_temp = int(match.group(4))
            wind = match.group(5)
            wind_speed = match.group(6)
            weather_data.append([city_name, date, cloud, high_temp, low_temp, wind, wind_speed])

# 将数据转换为 pandas DataFrame
df = pd.DataFrame(weather_data, columns=["City", "Date", "Cloud", "High Temp", "Low Temp", "Wind", "Wind Speed"])

# 数据清洗

# 日期处理：将日期转换为“YYYY-MM-DD”的格式
# 假设基准日期为 2024-12-23
base_date = datetime.date(2024, 12, 23)

# 日期解析函数
def parse_date(date_str):
    date_str = date_str.strip()

    if "今天" in date_str:
        return base_date
    elif "明天" in date_str:
        return base_date + datetime.timedelta(days=1)
    elif "后天" in date_str:
        return base_date + datetime.timedelta(days=2)
    elif "周" in date_str:
        target_weekday = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'].index(date_str[-2:])
        current_weekday = base_date.weekday()
        days_ahead = (target_weekday - current_weekday + 7) % 7
        return base_date + datetime.timedelta(days=days_ahead)
    elif "日" in date_str:
        day = int(date_str.replace("日", "").strip())
        return datetime.date(base_date.year, base_date.month, day)
    return None


# 温度列处理：将高温和低温转换为数值类型
df['High Temp'] = pd.to_numeric(df['High Temp'], errors='coerce')
df['Low Temp'] = pd.to_numeric(df['Low Temp'], errors='coerce')


def extract_wind_speed(wind_speed):
    # 处理带有 "转" 的风速（如 "3-4级转4-5级"）
    if '转' in wind_speed:
        # 取 "转" 前面的部分（例如 "3-4级转4-5级" -> "3-4级"）
        wind_speed = wind_speed.split('转')[0]

    # 处理风速范围（如 "3-4级"）
    if '-' in wind_speed:
        # 获取范围的最小值
        min_speed = int(wind_speed.split('-')[0].strip().replace('级', '').replace('<', ''))
    # 处理小于某个风速（如 "<3级"）
    elif '<' in wind_speed:
        min_speed = 3  # 小于3级的风速统一处理为3
    else:
        # 直接取风速的数字部分（例如 "3级" -> 3）
        min_speed = int(wind_speed.replace('级', '').replace('<', '').strip())

    return min_speed


df['Wind Speed'] = df['Wind Speed'].apply(extract_wind_speed)

# 处理风向：将风向转换为类别数据
df['Wind'] = df['Wind'].astype('category')

# 保存清洗后的数据到 CSV 文件
cleaned_csv_path = os.path.join(output_dir, "cleaned_weather.csv")
df.to_csv(cleaned_csv_path, index=False, encoding="utf-8-sig")
print(f"清洗后的数据已保存到: {cleaned_csv_path}")

### 可视化部分

# 绘制温度变化图
def plot_temperature(df, city_name):
    city_data = df[df['City'] == city_name]

    plt.figure(figsize=(10, 6))
    plt.plot(city_data['Date'], city_data['High Temp'], label='High Temp', color='red', marker='o')
    plt.plot(city_data['Date'], city_data['Low Temp'], label='Low Temp', color='blue', marker='o')

    plt.title(f'7-day Temperature Forecast for {city_name}')
    plt.xlabel('Date')
    plt.ylabel('Temperature (°C)')
    plt.xticks(rotation=45)
    plt.legend()
    plt.grid(True)
    # 保存图片
    plt.savefig(os.path.join(output_dir, f"{city_name}_temperature.png"))
    plt.close()

# 绘制风速分布图
def plot_wind_speed(df):
    plt.figure(figsize=(10, 6))
    sns.boxplot(x='Wind', y='Wind Speed', data=df)
    plt.title('Wind Speed Distribution by Wind Direction')
    plt.xlabel('Wind Direction')
    plt.ylabel('Wind Speed (Level)')
    # 保存图片
    plt.savefig(os.path.join(output_dir, "wind_speed_distribution.png"))
    plt.close()

# 绘制云层类型频率图
def plot_cloud_frequency(df):
    plt.figure(figsize=(10, 6))
    cloud_counts = df['Cloud'].value_counts()
    sns.barplot(x=cloud_counts.index, y=cloud_counts.values)
    plt.title('Cloud Type Frequency')
    plt.xlabel('Cloud Type')
    plt.ylabel('Frequency')
    # 保存图片
    plt.savefig(os.path.join(output_dir, "cloud_type_frequency.png"))
    plt.close()

# 绘制各城市的温度趋势图
def plot_all_cities_temperature(df):
    cities = df['City'].unique()

    plt.figure(figsize=(12, 8))

    for city in cities:
        city_data = df[df['City'] == city]
        plt.plot(city_data['Date'], city_data['High Temp'], label=f'{city} High Temp', marker='o')
        plt.plot(city_data['Date'], city_data['Low Temp'], label=f'{city} Low Temp', marker='x')

    plt.title('7-day Temperature Forecast for All Cities')
    plt.xlabel('Date')
    plt.ylabel('Temperature (°C)')
    plt.xticks(rotation=45)
    plt.legend(loc='upper left', bbox_to_anchor=(1, 1))
    plt.grid(True)
    plt.tight_layout()
    # 保存图片
    plt.savefig(os.path.join(output_dir, "all_cities_temperature.png"))
    plt.close()

### 运行可视化操作

# 城市的温度趋势图
plot_temperature(df, '青岛')
plot_temperature(df, '潍坊')
plot_temperature(df, '济南')
plot_temperature(df, '烟台')
plot_temperature(df, '淄博')
plot_temperature(df, '聊城')
plot_temperature(df, '德州')
plot_temperature(df, '济宁')
plot_temperature(df, '威海')
plot_temperature(df, '泰安')
plot_temperature(df, '滨州')
plot_temperature(df, '菏泽')
plot_temperature(df, '日照')
plot_temperature(df, '临沂')
plot_temperature(df, '枣庄')
plot_temperature(df, '东营')


# 风速分布图
plot_wind_speed(df)

# 云层类型频率图
plot_cloud_frequency(df)

# 各城市的温度变化对比
plot_all_cities_temperature(df)

print(f"可视化图表已保存到: {output_dir}")
